/******************************************************************************
 *
 * File Name    : adc.c
 *
 * Version      : V1.0
 *
 * Date         : 
 *
 * Author       : 
 *
 * Note: 
 *
 *****************************************************************************/

#include <stdio.h>
#include <rtthread.h>

#include "gd32f10x.h"
#include "define.h"

#include <string.h>
#include "drv_i2c.h"
#include "define.h"
#include <math.h>

ADC_DATA adc_data[Channel_Num];

/*!
    \brief      configure the different system clocks
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void rcu_config(void)
{

	rcu_periph_clock_enable(RCU_AF);
	
    /* enable GPIOC clock */
    rcu_periph_clock_enable(RCU_GPIOC);
    /* enable GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);  
    /* enable GPIOB clock */
    rcu_periph_clock_enable(RCU_GPIOB); 

    /* enable ADC0 clock */
    rcu_periph_clock_enable(RCU_ADC1);
    /* config ADC clock */
    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV16);
}

/*!
    \brief      configure the GPIO peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void gpio_config(void)
{
    /* config the GPIO as analog mode */  
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0);	//ADC012_IN0 // TEMP1-PA0
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4); // ADC01_IN4 // IS_12V-PA4
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_5);  //ADC01_IN5 // IS_3.3V-PA5
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_6); // ADC01_IN6 // IS_5V-PA6
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_7); // ADC01_IN7 // IS_3.3VSB-PA7
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4); // ADC01_IN14 // IS_B1-PC4
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_5); // ADC01_IN15 // IS_B2-PC5
    
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0); // ADC012_IN10 // VO_12V-PC0
    gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0);  //ADC01_IN8 // VO_3.3V-PB0
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_2); // ADC012_IN12 // VO_5V-PC2
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_3); // ADC012_IN13 // VO_3.3VSB-PC3
     gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_1); // ADC012_IN11 // VO_B1-PC1
    gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_1); // ADC01_IN9 // VO_B2-PB1
}

/*!
    \brief      configure the ADC peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void adc_config(void)
{
	/* reset ADC */
	adc_deinit(ADC1);
//	adc_deinit(ADC2);

    /* configure the ADC sync mode */
    adc_mode_config(ADC_MODE_FREE);  


   /* ADC scan mode function enable */
    adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
	
    /* ADC data alignment config */
    adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
//    adc_data_alignment_config(ADC2, ADC_DATAALIGN_RIGHT);
	
    /* ADC channel length config */
    adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL, 1);
//    adc_channel_length_config(ADC2, ADC_REGULAR_CHANNEL, ADC2_Channel_Num);
  

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
//    adc_external_trigger_source_config(ADC2, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); 
    /* ADC external trigger enable */
    adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);
 //   adc_external_trigger_config(ADC2, ADC_REGULAR_CHANNEL, ENABLE);
   
    /* enable ADC interface */
    adc_enable(ADC1);
    rt_thread_delay(10);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC1);
}

/**
  * @brief  ADC with DMA configuration
  * @param  None
  * @retval None
  */
static void ADC_DMA_Config(void)
{
	rcu_config();
	gpio_config();
	adc_config();
}


/**
 @brief ADC��ȡ
 @param channel -[in] ADCͨ��
 @return ADC����ֵ
*/
static uint16_t ADC_Read(uint8_t channel)
{
    uint16_t adcValue = 0;
    
    // ����ADCͨ��ת��˳�򣬲���ʱ��Ϊ55.5��ʱ������
    adc_regular_channel_config(ADC1, 0, channel, ADC_SAMPLETIME_55POINT5);
    // ����û�в����ⲿ����������ʹ����������ADCת��
    adc_software_trigger_enable(ADC1, ADC_REGULAR_CHANNEL);   
    
    while(!adc_flag_get(ADC1, ADC_FLAG_EOC));   // �ȴ��������
    adc_flag_clear(ADC1, ADC_FLAG_EOC); // ���������־
    
    adcValue = adc_regular_data_read(ADC1);  // ��ȡADC����
    return adcValue;
}

static void ADC_Read_ALL(void)
{
	uint8_t	i=0;
	
//		adc_data[AD_TEMP].AD_INS = ADC_Read(ADC_CHANNEL_0); //ADC012_IN0 // TEMP1-PA0
		adc_data[AD_IS_12V].AD_INS =ADC_Read(ADC_CHANNEL_4);// ADC01_IN4 // IS_12V-PA4
//		adc_data[AD_IS_5V].AD_INS = ADC_Read(ADC_CHANNEL_6);  //ADC01_IN6 // IS_5V-PA6
//		adc_data[AD_IS_33V].AD_INS = ADC_Read(ADC_CHANNEL_5);  // ADC01_IN5 // IS_3.3V-PA5
		adc_data[AD_IS_33SV].AD_INS = ADC_Read(ADC_CHANNEL_7); // ADC01_IN7 // IS_3.3VSB-PA7
//		adc_data[AD_IS_B1].AD_INS = ADC_Read(ADC_CHANNEL_14); // ADC01_IN14 // IS_B1-PC4
//		adc_data[AD_IS_B2].AD_INS = ADC_Read(ADC_CHANNEL_15); // ADC01_IN15 // IS_B2-PC5

		adc_data[AD_VO_12V].AD_INS = ADC_Read(ADC_CHANNEL_10); // ADC012_IN10 // VO_12V-PC0
//		adc_data[AD_VO_5V].AD_INS = ADC_Read(ADC_CHANNEL_12);  //ADC012_IN12  // VO_5V-PC2
//		adc_data[AD_VO_33V].AD_INS = ADC_Read(ADC_CHANNEL_8); // ADC01_IN8 // VO_3.3V-PB0
		adc_data[AD_VO_33SV].AD_INS = ADC_Read(ADC_CHANNEL_13); // ADC012_IN13 // VO_3.3VSB-PC3
//		adc_data[AD_VO_B1].AD_INS = ADC_Read(ADC_CHANNEL_11); // ADC012_IN11 // VO_B1-PC1
//		adc_data[AD_VO_B2].AD_INS = ADC_Read(ADC_CHANNEL_9);// ADC01_IN9 // VO_B2-PB1
		
		for(i=0;i<Channel_Num;i++){
			adc_data[i].AD_SUM = adc_data[i].AD_SUM + adc_data[i].AD_INS - (adc_data[i].AD_SUM>>2);
			adc_data[i].AD_AVG = adc_data[i].AD_SUM>>2;
		}
}

static void PVI_Calculate(void)
{
		ipmi_data.sensor_temp[0] = Get_Temperature(SD5075_ADDR0);

		ipmi_data.sensor_I33SV  = (uint16_t)(adc_data[AD_IS_33SV].AD_AVG * K_I33SV>>9)+B_I33SV;
		ipmi_data.sensor_I12V = (uint16_t)(adc_data[AD_IS_12V].AD_AVG * K_I12V>>9)+B_I12V;
		ipmi_data.sensor_V33SV = (uint16_t)(adc_data[AD_VO_33SV].AD_AVG * K_V33SV>>12);
		ipmi_data.sensor_V12V = (uint16_t)(adc_data[AD_VO_12V].AD_AVG * K_V12V>>12);

		ipmi_data.sensor_P12V = ipmi_data.sensor_I12V * ipmi_data.sensor_V12V/10000;
		ipmi_data.sensor_P33SV = ipmi_data.sensor_I33SV * ipmi_data.sensor_V33SV/10000;
}

static void adc_thread_entry(void *arg)
{
	
	ADC_DMA_Config();
	IIC_Init();
	
       while (1)
       {
    	rt_thread_delay(20);
		ADC_Read_ALL();	// �����˲�

		rt_thread_delay(1);
		PVI_Calculate();
       }
}

int adc_start(void)
{
    rt_thread_t tid;

    tid = rt_thread_create("adc", adc_thread_entry, RT_NULL,1024, 3, 50);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }

    return 0;
}


int cmd_show_sensor(int argc, char **argv)
{
    rt_kprintf("show sensor all:\n");
    rt_kprintf("---------------------------------------------------\n");
    rt_kprintf("sensor	voltage/current		designed\n");
	rt_kprintf("1	voltage:%d.%02d		(12V)\n", ipmi_data.sensor_V12V/100,ipmi_data.sensor_V12V%100);
	rt_kprintf("1	current:%d.%02d		(0~80A)\n", ipmi_data.sensor_I12V/100,ipmi_data.sensor_I12V%100);
	rt_kprintf("1	power:%dW\n", ipmi_data.sensor_P12V);
rt_kprintf("\n");
	rt_kprintf("2	voltage:%d.%02d		(5V)\n", ipmi_data.sensor_V5V/100,ipmi_data.sensor_V5V%100);
	rt_kprintf("2	current:%d.%02d		(0~80A)\n", ipmi_data.sensor_I5V/100,ipmi_data.sensor_I5V%100);
	rt_kprintf("2	power:%dW\n", ipmi_data.sensor_P5V);
rt_kprintf("\n");	
	rt_kprintf("3	voltage:%d.%02d		(3.3V)\n", ipmi_data.sensor_V33V/100,ipmi_data.sensor_V33V%100);
	rt_kprintf("3	current:%d.%02d		(0~20A)\n", ipmi_data.sensor_I33V/100,ipmi_data.sensor_I33V%100);
	rt_kprintf("3	power:%dW\n", ipmi_data.sensor_P33V);
rt_kprintf("\n");
	rt_kprintf("4	voltage:%d.%02d		(3.3SV)\n", ipmi_data.sensor_V33SV/100,ipmi_data.sensor_V33SV%100);
	rt_kprintf("4	current:%d.%02d		(0~20A)\n", ipmi_data.sensor_I33SV/100,ipmi_data.sensor_I33SV%100);
	rt_kprintf("4	power:%dW\n", ipmi_data.sensor_P33SV);
rt_kprintf("\n");
	rt_kprintf("5	voltage:%d.%02d		(B1_V)\n", ipmi_data.sensor_VB1V/100,ipmi_data.sensor_VB1V%100);
	rt_kprintf("5	current:%d.%02d		(0~20A)\n", ipmi_data.sensor_IB1V/100,ipmi_data.sensor_IB1V%100);
	rt_kprintf("5	power:%dW\n", ipmi_data.sensor_PB1V);
rt_kprintf("\n");
	rt_kprintf("6	voltage:%d.%02d		(B2_V)\n", ipmi_data.sensor_VB2V/100,ipmi_data.sensor_VB2V%100);
	rt_kprintf("6	current:%d.%02d		(0~20A)\n", ipmi_data.sensor_IB2V/100,ipmi_data.sensor_IB2V%100);
	rt_kprintf("6	power:%dW\n", ipmi_data.sensor_PB2V);
rt_kprintf("\n");	
	rt_kprintf("7	temperature0:%d.%02d		(-55~+125 Degree C)\n", ipmi_data.sensor_temp[0]/100, (abs(ipmi_data.sensor_temp[0]))%100);
	rt_kprintf("7	temperature1:%d.%02d		(-55~+125 Degree C)\n", ipmi_data.sensor_temp[1]/100, (abs(ipmi_data.sensor_temp[1]))%100);
	rt_kprintf("7	temperature2:%d.%02d		(-55~+125 Degree C)\n", ipmi_data.sensor_temp[2]/100, (abs(ipmi_data.sensor_temp[2]))%100);
	
    rt_kprintf("\n");

    return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_show_sensor, __cmd_show_sensor, show sensor.);

#define I2C0_SLAVE_ADDRESS 0xa8

int cmd_show_test(int argc, char **argv)
{
    int ret;
    int i = 0;
    uint8_t iic_arr[5] = {0x00, 0x01, 0x02, 0x03, 0x04};
    rt_kprintf("test iic=====================\n");
    for(i = 0; i <= 10; i++) {
        i2c_init_data(I2C0, I2C_MASTER_CH, I2C0_SLAVE_ADDRESS);
        ret = i2c_master_send(I2C0, I2C0_SLAVE_ADDRESS, (uint8_t *)iic_arr, sizeof(iic_arr));
        if (ret)
        {
            rt_kprintf("%s: i2c_master_send error!\n", __func__);
        }
        i2c_init_data(I2C0, I2C_SLAVE_CH, ipmi_data.slave_add);
        rt_kprintf("test iic======msat send!!!!\n");
		rt_thread_delay(1000);
    }
}

FINSH_FUNCTION_EXPORT_ALIAS(cmd_show_test, __cmd_show_test, show test.);